package com.budwk.app.miniapp.controllers.admin;

import cn.dev33.satoken.annotation.SaCheckLogin;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.miniapp.common.CommonConstants;
import com.budwk.app.miniapp.common.ConfigConstant;
import com.budwk.app.miniapp.models.WxUser;
import com.budwk.app.miniapp.services.WxUserService;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.common.result.ResultCode;
import com.budwk.starter.common.page.Pagination;
import com.budwk.starter.common.page.PageUtil;
import com.budwk.starter.log.annotation.SLog;
import com.budwk.starter.security.utils.SecurityUtil;
import com.budwk.app.miniapp.models.WxMsg;
import com.budwk.app.miniapp.services.WxmsgService;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpKefuService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.*;
import org.nutz.lang.Strings;
import com.budwk.starter.common.openapi.annotation.*;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@IocBean
@At("/platform/miniapp/msg")
@ApiDefinition(tag = "微信小程序消息管理")
@Slf4j
public class WxmsgController {
    @Inject
    private WxmsgService wxMsgService;

    @Inject
    private WxUserService wxuserService;

    @Inject
    private WxMpService wxService;

    /**
     * 分页查询小程序消息
     *
     * @param bean
     * @param pageNo
     * @param pageSize
     * @param pageOrderName
     * @param pageOrderBy
     * @return
     */
    @At
    @Ok("json")
    @POST
    @ApiOperation(name = "分页查询小程序消息")
    @ApiFormParams(
            value = {
                    @ApiFormParam(name = "pageNo", example = "1", description = "页码", type = "integer"),
                    @ApiFormParam(name = "pageSize", example = "10", description = "页大小", type = "integer"),
                    @ApiFormParam(name = "pageOrderName", example = "createdAt", description = "排序字段"),
                    @ApiFormParam(name = "pageOrderBy", example = "descending", description = "排序方式")
            },
            implementation = WxMsg.class
    )
    @ApiResponses(
            implementation = WxMsg.class
    )
    @SaCheckLogin
    public Result<?> list(@Param("..") WxMsg bean,
                          @Param("pageNo") int pageNo,
                          @Param("pageSize") int pageSize,
                          @Param("pageOrderName") String pageOrderName,
                          @Param("pageOrderBy") String pageOrderBy) {
        Cnd cnd = Cnd.NEW();
        if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
            cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
        }
        if (bean.getCreateId() != null && Strings.isNotBlank(bean.getCreateId().toString())) {
            cnd.and("createId", "=", bean.getCreateId());
        }
        if (bean.getCreateTime() != null && Strings.isNotBlank(bean.getCreateTime().toString())) {
            cnd.and("create_time", "=", bean.getCreateTime());
        }
        if (bean.getUpdateId() != null && Strings.isNotBlank(bean.getUpdateId().toString())) {
            cnd.and("update_id", "=", bean.getUpdateId());
        }
        if (bean.getUpdateTime() != null && Strings.isNotBlank(bean.getUpdateTime().toString())) {
            cnd.and("update_time", "=", bean.getUpdateTime());
        }
        if (bean.getRemark() != null && Strings.isNotBlank(bean.getRemark().toString())) {
            cnd.and("remark", "=", bean.getRemark());
        }
        if (bean.getAppName() != null && Strings.isNotBlank(bean.getAppName().toString())) {
            cnd.and("appName", "=", bean.getAppName());
        }
        if (bean.getAppLogo() != null && Strings.isNotBlank(bean.getAppLogo().toString())) {
            cnd.and("appLogo", "=", bean.getAppLogo());
        }
        if (bean.getWxUserId() != null && Strings.isNotBlank(bean.getWxUserId().toString())) {
            cnd.and("wxUserId", "=", bean.getWxUserId());
        }
        if (bean.getNickName() != null && Strings.isNotBlank(bean.getNickName().toString())) {
            cnd.and("nickName", "=", bean.getNickName());
        }
        if (bean.getHeadimgUrl() != null && Strings.isNotBlank(bean.getHeadimgUrl().toString())) {
            cnd.and("headimgUrl", "=", bean.getHeadimgUrl());
        }
        if (bean.getType() != null && Strings.isNotBlank(bean.getType().toString())) {
            cnd.and("type", "=", bean.getType());
        }
        if (bean.getRepType() != null && Strings.isNotBlank(bean.getRepType().toString())) {
            cnd.and("repType", "=", bean.getRepType());
        }
        if (bean.getRepEvent() != null && Strings.isNotBlank(bean.getRepEvent().toString())) {
            cnd.and("repEvent", "=", bean.getRepEvent());
        }
        if (bean.getRepContent() != null && Strings.isNotBlank(bean.getRepContent().toString())) {
            cnd.and("repContent", "=", bean.getRepContent());
        }
        if (bean.getRepMediaId() != null && Strings.isNotBlank(bean.getRepMediaId().toString())) {
            cnd.and("repMediaId", "=", bean.getRepMediaId());
        }
        if (bean.getRepName() != null && Strings.isNotBlank(bean.getRepName().toString())) {
            cnd.and("repName", "=", bean.getRepName());
        }
        if (bean.getRepDesc() != null && Strings.isNotBlank(bean.getRepDesc().toString())) {
            cnd.and("repDesc", "=", bean.getRepDesc());
        }
        if (bean.getRepUrl() != null && Strings.isNotBlank(bean.getRepUrl().toString())) {
            cnd.and("repUrl", "=", bean.getRepUrl());
        }
        if (bean.getRepHqUrl() != null && Strings.isNotBlank(bean.getRepHqUrl().toString())) {
            cnd.and("repHqUrl", "=", bean.getRepHqUrl());
        }
        if (bean.getContent() != null && Strings.isNotBlank(bean.getContent().toString())) {
            cnd.and("content", "=", bean.getContent());
        }
        if (bean.getRepThumbMediaId() != null && Strings.isNotBlank(bean.getRepThumbMediaId().toString())) {
            cnd.and("repThumbMediaId", "=", bean.getRepThumbMediaId());
        }
        if (bean.getRepThumbUrl() != null && Strings.isNotBlank(bean.getRepThumbUrl().toString())) {
            cnd.and("repThumbUrl", "=", bean.getRepThumbUrl());
        }
        if (bean.getRepLocationX() != null && Strings.isNotBlank(bean.getRepLocationX().toString())) {
            cnd.and("repLocationX", "=", bean.getRepLocationX());
        }
        if (bean.getRepLocationY() != null && Strings.isNotBlank(bean.getRepLocationY().toString())) {
            cnd.and("repLocationY", "=", bean.getRepLocationY());
        }
        if (bean.getRepScale() != null && Strings.isNotBlank(bean.getRepScale().toString())) {
            cnd.and("repScale", "=", bean.getRepScale());
        }
        if (bean.getReadFlag() != null && Strings.isNotBlank(bean.getReadFlag().toString())) {
            cnd.and("readFlag", "=", bean.getReadFlag());
        }
        if (StringUtils.isNotBlank(bean.getNotInRepType())) {
            return Result.success(wxMsgService.listWxMsgMapGroup(pageNo, pageSize, bean));
        }
        Pagination pagination = wxMsgService.listPage(pageNo, pageSize, cnd);
        if (StringUtils.isNotBlank(bean.getWxUserId())) {//标记为已读
            Sql sql = wxMsgService.execute(Sqls.create("update wx_msg set read_flag = @read_flag1 where wx_user_id = @wx_user_id and read_flag = @read_flag2")
                            .setParam("read_flag1", CommonConstants.YES))
                    .setParam("wx_user_id", bean.getWxUserId())
                    .setParam("read_flag2", CommonConstants.NO);
        }
        return Result.data(pagination);
    }

    /**
     * 新增小程序消息
     *
     * @param wxMsg
     * @param req
     * @return
     */
    @At
    @Ok("json")
    @POST
    @ApiOperation(name = "新增小程序消息")
    @ApiFormParams(
            implementation = WxMsg.class
    )
    @ApiResponses
    @SLog(tag = "新增小程序消息", value = "${args[0].id}")
    @SaCheckLogin
    public Result<?> create(@Param("..") WxMsg wxMsg, HttpServletRequest req) {
        wxMsg.setCreatedBy(SecurityUtil.getUserId());
        try {
            WxUser wxUser = wxuserService.fetch(wxMsg.getWxUserId());
            //入库
            wxMsg.setNickName(wxUser.getNickName());
            wxMsg.setHeadimgUrl(wxUser.getHeadImgUrl());
            wxMsg.setCreateTime(LocalDateTime.now());
            wxMsg.setType(ConfigConstant.WX_MSG_TYPE_2);
            WxMpKefuMessage wxMpKefuMessage = null;
            if (WxConsts.KefuMsgType.TEXT.equals(wxMsg.getRepType())) {
                wxMsg.setRepContent(wxMsg.getRepContent());
                wxMpKefuMessage = WxMpKefuMessage.TEXT().build();
                wxMpKefuMessage.setContent(wxMsg.getRepContent());
            }
            if (WxConsts.KefuMsgType.IMAGE.equals(wxMsg.getRepType())) {//图片
                wxMsg.setRepName(wxMsg.getRepName());
                wxMsg.setRepUrl(wxMsg.getRepUrl());
                wxMsg.setRepMediaId(wxMsg.getRepMediaId());
                wxMpKefuMessage = WxMpKefuMessage.IMAGE().build();
                wxMpKefuMessage.setMediaId(wxMsg.getRepMediaId());
            }
            if (WxConsts.KefuMsgType.VOICE.equals(wxMsg.getRepType())) {
                wxMsg.setRepName(wxMsg.getRepName());
                wxMsg.setRepUrl(wxMsg.getRepUrl());
                wxMsg.setRepMediaId(wxMsg.getRepMediaId());
                wxMpKefuMessage = WxMpKefuMessage.VOICE().build();
                wxMpKefuMessage.setMediaId(wxMsg.getRepMediaId());
            }
            if (WxConsts.KefuMsgType.VIDEO.equals(wxMsg.getRepType())) {
                wxMsg.setRepName(wxMsg.getRepName());
                wxMsg.setRepDesc(wxMsg.getRepDesc());
                wxMsg.setRepUrl(wxMsg.getRepUrl());
                wxMsg.setRepMediaId(wxMsg.getRepMediaId());
                wxMpKefuMessage = WxMpKefuMessage.VIDEO().build();
                wxMpKefuMessage.setMediaId(wxMsg.getRepMediaId());
                wxMpKefuMessage.setTitle(wxMsg.getRepName());
                wxMpKefuMessage.setDescription(wxMsg.getRepDesc());
            }
            if (WxConsts.KefuMsgType.MUSIC.equals(wxMsg.getRepType())) {
                wxMsg.setRepName(wxMsg.getRepName());
                wxMsg.setRepDesc(wxMsg.getRepDesc());
                wxMsg.setRepUrl(wxMsg.getRepUrl());
                wxMsg.setRepHqUrl(wxMsg.getRepHqUrl());
                wxMpKefuMessage = WxMpKefuMessage.MUSIC().build();
                wxMpKefuMessage.setTitle(wxMsg.getRepName());
                wxMpKefuMessage.setDescription(wxMsg.getRepDesc());
                wxMpKefuMessage.setMusicUrl(wxMsg.getRepUrl());
                wxMpKefuMessage.setHqMusicUrl(wxMsg.getRepHqUrl());
                wxMpKefuMessage.setThumbMediaId(wxMsg.getRepThumbMediaId());
            }
            if (WxConsts.KefuMsgType.NEWS.equals(wxMsg.getRepType())) {
                List<WxMpKefuMessage.WxArticle> list = new ArrayList<>();
                JSONArray jSONArray = null;// wxMsg.getContent().getJSONArray("articles");
                WxMpKefuMessage.WxArticle t;
                for (Object object : jSONArray) {
                    JSONObject jSONObject = JSON.parseObject(object.toString());
                    t = new WxMpKefuMessage.WxArticle();
                    t.setTitle(jSONObject.getString("title"));
                    t.setDescription(jSONObject.getString("digest"));
                    t.setPicUrl(jSONObject.getString("thumbUrl"));
                    t.setUrl(jSONObject.getString("url"));
                    list.add(t);
                }
                wxMsg.setRepName(wxMsg.getRepName());
                wxMsg.setRepDesc(wxMsg.getRepDesc());
                wxMsg.setRepUrl(wxMsg.getRepUrl());
                wxMsg.setRepMediaId(wxMsg.getRepMediaId());
                wxMsg.setContent(wxMsg.getContent());
                wxMpKefuMessage = WxMpKefuMessage.NEWS().build();
                wxMpKefuMessage.setArticles(list);
            }
            if (wxMpKefuMessage != null) {
                WxMpKefuService wxMpKefuService = wxService.getKefuService();
                wxMpKefuMessage.setToUser(wxUser.getOpenId());
                wxMpKefuService.sendKefuMessage(wxMpKefuMessage);
                wxMsgService.insert(wxMsg);
                return Result.success(wxMsg);
            } else {
                return Result.error("非法消息类型");
            }
        } catch (WxErrorException e) {
            e.printStackTrace();
            log.error("新增微信消息失败" + e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 修改小程序消息
     *
     * @param wxMsg
     * @param req
     * @return
     */
    @At
    @Ok("json")
    @POST
    @ApiOperation(name = "修改小程序消息")
    @ApiFormParams(
            implementation = WxMsg.class
    )
    @ApiResponses
    @SLog(tag = "修改小程序消息", value = "${args[0].id}")
    @SaCheckLogin
    public Result<?> update(@Param("..") WxMsg wxMsg, HttpServletRequest req) {
        wxMsg.setUpdatedBy(SecurityUtil.getUserId());
        wxMsgService.updateIgnoreNull(wxMsg);
        return Result.success();
    }

    /**
     * 获取小程序消息
     *
     * @param id
     * @param req
     * @return
     */
    @At("/get")
    @Ok("json")
    @POST
    @ApiOperation(name = "获取小程序消息")
    @ApiFormParams(
            {
                    @ApiFormParam(name = "id", description = "唯一标识", required = true, check = true)
            }
    )
    @SaCheckLogin
    public Result<?> getData(@Param("id") String id, HttpServletRequest req) {
        WxMsg wxMsg = wxMsgService.fetch(id);
        if (wxMsg == null) {
            return Result.error(ResultCode.NULL_DATA_ERROR);
        }
        return Result.data(wxMsg);
    }

    /**
     * 删除小程序消息
     *
     * @param id
     * @param req
     * @return
     */
    @At("/delete")
    @Ok("json")
    @POST
    @ApiOperation(name = "删除小程序消息")
    @ApiFormParams(
            {
                    @ApiFormParam(name = "id", description = "唯一标识", required = true, check = true)
            }
    )
    @SLog(tag = "删除小程序消息", value = "${args[0]}")
    @SaCheckLogin
    public Result<?> delete(@Param("id") String id, HttpServletRequest req) {
        WxMsg wxMsg = wxMsgService.fetch(id);
        if (wxMsg == null) {
            return Result.error(ResultCode.NULL_DATA_ERROR);
        }
        wxMsgService.delete(id);
        req.setAttribute("_slog_msg", wxMsg.getId());
        return Result.success();
    }
}
